﻿using System;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Media.Imaging;

using Automator.Tasks.Core;
using Automator.Tasks.Windows;

namespace Automator.Tasks
{
    /// <summary>
    /// Class for downloading a file from the web.
    /// Defined attributes:
    /// UrlName: specifies URL of the file
    /// LocalName: specifies the name of downloaded file
    /// </summary>
    public class FileDownloadTask: Task, ITaskExecutable
    {
        #region ITaskExecutableMembers
        
        public void Execute(WorkflowExecutionContext context)
        {
            Thread t = new Thread(new ParameterizedThreadStart(DownloadFile));
            t.SetApartmentState(ApartmentState.STA);
            t.Start(new TaskThreadingContext(this, context));
            t.Join();
            if (ThreadException != null)
                throw new TaskExecutionException(ThreadException.Message, ThreadException);
        }
        
        /// <summary>
        /// Field for catch an exception in a thread
        /// </summary>
        private static Exception ThreadException;
        
        /// <summary>
        /// Sync object
        /// </summary>
        private static object locker = new object();

        private void DownloadFile(object arg)
        {
            lock (locker)
            {
                try
                {
                    FileDownloadTask task = (FileDownloadTask)(arg as TaskThreadingContext).Task;
                    WorkflowExecutionContext context = (arg as TaskThreadingContext).ExecutionContext;
                    using (WebClient client = new WebClient())
                    {
                        client.Proxy = Automator.Runtime.Settings.Proxy;
                        FileDownloadTaskExecuteWindow window = new FileDownloadTaskExecuteWindow();
                        string webFile = context.DereferenceVariables(task.Attributes["UrlName"].Value);
                        string localFile = context.DereferenceVariables(task.Attributes["LocalName"].Value);
                        window.lblFileName.Text = String.Format("Downloading {0} ...", Path.GetFileName(webFile));
                        window.Show();
                        client.DownloadFile(new Uri(webFile), localFile);
                        window.allowClosing = true;
                        window.Close();
                        ThreadException = null;
                    }
                }
                catch (Exception ex)
                {
                    ThreadException = ex;
                }
            }
        }
        
        #endregion
        
        public FileDownloadTask():
            base()
        {
            this.Title = "File Download";
            this.Description = "Download file from the web";
            this.TaskImage = new BitmapImage(new Uri("/Automator.Tasks.Net;component/Resources/download.png", UriKind.Relative));

            this.Attributes.Add(new TaskAttributeDefinition() { Key = "UrlName", Value = String.Empty });
            this.Attributes.Add(new TaskAttributeDefinition() { Key = "LocalName", Value = String.Empty });
        }
        
        public override string CommandText
        {
            get { return this.Attributes["UrlName"].Value.ToString().Trim(); }
            set { base.CommandText = value; }
        }
        
        public override bool EditTask()
        {
            base.EditTask();
            FileDownloadTaskEditWindow window = new FileDownloadTaskEditWindow();
            window.Owner = Application.Current.MainWindow;
            window.Title = String.Format("Edit {0} Task", this.Title);
            //performing binding to the header
            window.header.ContentPanel.DataContext = this;

            window.edtWebFile.Text = this.Attributes["UrlName"].Value.ToString();
            window.edtLocalFile.Text = this.Attributes["LocalName"].Value.ToString();
            window.footer.BtnOK.Click += delegate { window.DialogResult = true; };

            if (window.ShowDialog() == true)
            {
                this.Attributes["UrlName"].Value = window.edtWebFile.Text.Trim();
                this.Attributes["LocalName"].Value = window.edtLocalFile.Text.Trim();
                this.CommandText = String.Empty;
                return true;
            }
            else return false;
        }
    }
}
